#ifndef GNAPP_H
#define GNAPP_H

#include "GnAppWindow.h"

class GnApp : public GnMemoryObject
{
public:
	virtual	~GnApp(void);

protected:
	GnApp(const gtchar* windowCaption, guint width = DEFAULT_WIDTH,
		guint height = DEFAULT_HEIGHT, bool useFrameSystem = false,
		guint menuID = 0, guint bitDepth = 0,
		gulong windowStyle = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX);

public:
	static int StartWinApp(HINSTANCE instance, LPTSTR cmdLine, int nCmdShow);
	static GnApp* Create();
	static void	SetOSInstance(GnInstance& instance);

	bool CreateGnWindow(int nCmdShow, GnInstance instance, GnWindowHandle parentHandle = NULL);
	bool CreateRenderer();
	bool Init();

#if defined(WIN32)
	static LRESULT CALLBACK WndProc(GnWindowHandle hWnd, UINT message, WPARAM wParam,LPARAM lParam);
	void Win32Loop();
#endif // #if defined(WIN32)

	void MainLoop();
	inline void ResetTimes();

	bool MeasureTime();

	inline void ResetFrameTimes();

	inline virtual void BeginUpdate();
	virtual void UpdateFrame();
	inline virtual void EndUpdate();

	inline virtual void BeginCull();
	virtual void CullFrame();
	inline virtual void EndCull();

	inline virtual void BeginFrame();
	virtual void RenderFrame();
	inline virtual void EndFrame();

	GNFORCEINLINE guint GetMenuID();
	GNFORCEINLINE GnAppWindow* GetAppWindow();

protected:
	static const guint DEFAULT_WIDTH = 1024;
	static const guint DEFAULT_HEIGHT = 768;

protected:
	static GnApp* msSingletone;	
	static GnInstance msWindowInstance;
	GnAppWindow* mpAppWindow;
	GnRenderer* mpRenderer;

	guint mMenuID;

	float mCurrentTime;
	float mLastTime;
	float mAccumTime;
	float mFrameTime;
	int mClicks;
	float mFrameRate;
	
	float mMinFramePeriod;
	float mLastFrame;

	float mBeginUpdateTime;
	float mUpdateTime;

	float mBeginCullTime;
	float mCullTime;

	float mBeginRenderTime;
	float mRenderTime;
};

#include "GnApp.inl"
#endif // GNAPP_H
